class Base():
    __a = "Base"  # 私有化类变量，外部不能访问
    a = "Base"  # 类变量，外部可以访问

    def __init__(self):
        self.b = "Base b"

    @classmethod
    def display(cls):
        print(f"class:{cls.__name__}")
        # print(f"class:{cls.__dict__}")
        print(f"__a:{cls.__a}")
        print(f"a:{cls.a}")

    def display2(self):
        print(f"__a:{self.__a}")
        print(f"a:{self.a}")


class Derived(Base):
    __a = "Derived"  # __a 灰色，意思是私有化类变量只有父类可以起作用?
    a = "Derived"
    # _Base__a = "Derived"


if __name__ == '__main__':
    # Base.display()  # Base
    # 因为继承类的类变量和父类一样，名字就被改为 __Derived__a
    # {'_Base_a': 'Base', 'a': 'Base'}
    # print(f"base dict:{Base.__dict__}")

    # {'b': 'Base b'} 实例化的 dict 储存了 成员变量 b
    # print(f"base dict:{Base().__dict__}")

    # {'_Derived__a': 'Derived', 'a': 'Base'}
    # print(f"derived dict:{Derived.__dict__}")
    # print(f"base a:{Base.a}")  # Base
    print(Base.__dict__["_Base__a"])  # Derived
    # print(f"derived a:{Derived.a}")  # Derived
    print(Derived.__dict__["_Derived__a"])  # Derived
    print("\r")

    # 子类的类变量和父类一样，就像这里的 __a。子类和父类对应的类变量在 __dict__ 里都会加上 _Base 和 _Derive 的前缀
    # 在类打印类变量的时候，都会去掉前缀。但是子类和父类都会显示父类的类变量的值
    # 但是这个只是针对 __a 这样的私有变量。也就说，私有的类变量如果重复，则只显示父类的值(很奇怪??)
    # 针对非私有变量的类变量，父类和子类都各自保存自己独立的
    # Base.display()  # Base Base
    # print("base display:")
    # Base.display()  # Base Base

    # print("\r")
    # print("base() display2:")
    # Base().display2()  # Base Base

    # print("\r")
    # print("derived display:")
    # Derived.display()  # Base(__a) Derived(a) 这里 derived 类显示的 __a 竟然是 base

    # print("\r")
    # print("derived() display2:")
    # Derived().display2()  # Base(__a) Derived(a) 这里 derived() 实例显示的 __a 竟然也是 base
